#region Using directives

using System;
using System.Collections.Generic;
using System.Text;

using Weazel.Math;
using Weazel.Gezel.Simulator.Reference.Profiling;

#endregion

namespace Weazel.Gezel.Simulator.Reference
{
    /// <summary>
    /// AbstractSignal serves as a base class for the
    /// various kinds of signals that drives the simulation.
    /// </summary>
    public abstract class AbstractSignal
    {
        /// <summary>
        /// The signal id
        /// </summary>
        private readonly Symid id;
        public Symid Id
        {
            get
            {
                return id;
            }
        }

        protected readonly string name;
        public string Name
        {
            get
            {
                return name;
            }
        }

        /// <summary>
        /// generation counter used in simulation
        /// </summary>
        protected long generation;

        /// <summary>
        /// Enumerates the states of the signal
        /// </summary>
        public enum EvaluationState { Stable, Evaluation };

        /// <summary>
        /// Used to detect cycles in the signal hiearchies
        /// during simulation. If a signal is asked to evaluate
        /// and its state is already set to EvaluationState.Evaluation
        /// a combinatorial loop has been detected
        /// </summary>
        public EvaluationState currentstate;

        /// <summary>
        /// The radix used to convert the value
        /// of the signal to a string litteral
        /// </summary>
        protected int @base;

        internal AbstractSignal(Symid id, string name)
        {
            this.id = id;
            this.name = name;
            this.generation = 0;
            this.currentstate = EvaluationState.Stable;
        }

        internal virtual void newDefiner(Symid context, AbstractSignal sig)
        {
            throw new NotImplementedException();
        }
        internal virtual uint Width()
        {
            throw new NotImplementedException();
        }
        internal virtual uint Signed()
        {
            throw new NotImplementedException();
        }

        internal virtual void defineDriver(AbstractSignal artsignal)
        {
            throw new NotImplementedException();
        }

        internal virtual Integer PeekValue()
        {
            throw new NotImplementedException();
        }

        internal virtual Integer Evaluate(AbstractIpBlock ip, long target_generation)
        {
            throw new NotImplementedException();
        }

        internal virtual void Assign(Integer v)
        {
            throw new NotImplementedException();
        }

        public virtual void SetBase(int @base)
        {
            this.@base = @base;
        }

        public virtual void Show(StringBuilder buffer)
        {
            buffer.Append(PeekValue().ToString(@base));
        }

        /// <summary>
        /// Called to determine if signal needs evaluation
        /// in the current cycle. Should be overridden
        /// in derived classes to provide no unnessecary 
        /// evaluations on derived signals
        /// </summary>
        /// <param name="g">current simulation cycle</param>
        /// <returns>false</returns>
        public virtual bool IsGeneration(long g)
        {
            return false;
        }

        public abstract bool TraceToSignal(Symid toSignalId, List<AbstractSignal> signals);
    }
}